#include "llib_version.h"
#define L_VERSION   1120118
#if L_VERSION == LLIB_VERSION_TO_TEST

#include <boost/test/unit_test.hpp>
#include <boost/mpl/list.hpp>
using namespace boost;

#include <llib.h>
using namespace llib;
using namespace llib::geom;

#include <vector>
using namespace std;

BOOST_AUTO_TEST_SUITE(BVTree2_test_suite)

typedef mpl::list<BVTree0,BVTree1,BVTree2,BVTree3,BVTree4,BVTree5,BVTree6,BVTree7> BVTreeTypes;

BOOST_AUTO_TEST_CASE_TEMPLATE(BVTree2_test_case_01, BVTree, BVTreeTypes) {

    const Int32 vertexNum = 16;
    vector<Vec3f> vertexList;
    vector<Vec3i> vertexFace;
    Vec3f vertexList0[vertexNum] = { Vec3f( 5.f, 7.f, 0.f), Vec3f( 5.f, 6.f, 0.f), Vec3f( 5.f, 4.f, 0.f), Vec3f( 5.f, 3.f, 0.f),
                                     Vec3f(-5.f, 7.f, 0.f), Vec3f(-5.f, 6.f, 0.f), Vec3f(-5.f, 4.f, 0.f), Vec3f(-5.f, 3.f, 0.f),
                                     Vec3f( 5.f,-7.f, 0.f), Vec3f( 5.f,-6.f, 0.f), Vec3f( 5.f,-4.f, 0.f), Vec3f( 5.f,-3.f, 0.f),
                                     Vec3f(-5.f,-7.f, 0.f), Vec3f(-5.f,-6.f, 0.f), Vec3f(-5.f,-4.f, 0.f), Vec3f(-5.f,-3.f, 0.f) };
    FOR(I,0,vertexNum) {
        FOR(J,0,3) vertexList.push_back(vertexList0[I]);
        vertexFace.push_back(Vec3i(I*3,I*3+1,I*3+2));
    }

    TriMesh mesh(vertexList, vertexFace);

    BVTree tree;
    tree.Init(mesh);

    Int32 counter = 0;
    BVTree::Iter* iter = tree.CreateIter(BVTree::Iter::Preorder);
    BVTree::BVNode* pNode = iter->Next();
    while(pNode != NULL) {
        pNode = iter->Next();
        ++counter;
    }
    BOOST_CHECK_EQUAL( counter, 31 );

    counter = 0;
    iter = tree.CreateIter(BVTree::Iter::Inorder);
    pNode = iter->Next();
    while(pNode != NULL) {
        pNode = iter->Next();
        ++counter;
    }
    BOOST_CHECK_EQUAL( counter, 31 );

    counter = 0;
    iter = tree.CreateIter(BVTree::Iter::Postorder);
    pNode = iter->Next();
    while(pNode != NULL) {
        pNode = iter->Next();
        ++counter;
    }
    BOOST_CHECK_EQUAL( counter, 31 );


    BOOST_CHECK_EQUAL( tree.GetNodeNum(), 31 );
    BOOST_CHECK_EQUAL( tree.GetLeafNum(), 16 );

    BVTree::BVNode* node = tree.GetRoot();
    BOOST_CHECK( node->IsRoot() );
    BOOST_CHECK( !node->IsLeaf() );

    BVTree::BVNode* node2 = node->GetChildLeft()->GetChildLeft()->GetChildLeft();
    BOOST_CHECK( !node2->IsRoot() );
    BOOST_CHECK( !node2->IsLeaf() );

    BVTree::BVNode* leaf1 = node2->GetChildLeft();
    BVTree::BVNode* leaf2 = node2->GetChildRight();
    BOOST_CHECK( leaf1->IsLeaf() );
    BOOST_CHECK( leaf2->IsLeaf() );
    BOOST_CHECK( abs(leaf1->GetLeafMeshFace().GetIndex() - leaf2->GetLeafMeshFace().GetIndex()) == 1 );
    BOOST_CHECK_EQUAL( leaf1->GetParent(), leaf2->GetParent() );

    node2 = node->GetChildRight()->GetChildLeft()->GetChildLeft();
    BOOST_CHECK( !node2->IsRoot() );
    BOOST_CHECK( !node2->IsLeaf() );

    leaf1 = node2->GetChildLeft();
    leaf2 = node2->GetChildRight();
    BOOST_CHECK( leaf1->IsLeaf() );
    BOOST_CHECK( leaf2->IsLeaf() );
    BOOST_CHECK( abs(leaf1->GetLeafMeshFace().GetIndex() - leaf2->GetLeafMeshFace().GetIndex()) == 1 );
    BOOST_CHECK_EQUAL( leaf1->GetParent(), leaf2->GetParent() );
    BOOST_CHECK_EQUAL( leaf1->GetParent(), node2 );

}

BOOST_AUTO_TEST_SUITE_END()

#endif
